1   /*
2    * Copyright (C) 2009 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.collect;
18  
19  import static com.google.common.collect.CollectPreconditions.checkEntryNotNull;
20  
21  import java.util.Map;
22  
23  /**
24   * GWT emulation of {@link ImmutableBiMap}.
25   *
26   * @author Hayward Chan
27   */
28  public abstract class ImmutableBiMap<K, V> extends ForwardingImmutableMap<K, V>
29      implements BiMap<K, V> {
30  
31    // Casting to any type is safe because the set will never hold any elements.
32    @SuppressWarnings("unchecked")
33    public static <K, V> ImmutableBiMap<K, V> of() {
34      return (ImmutableBiMap<K, V>) EmptyImmutableBiMap.INSTANCE;
35    }
36  
37    public static <K, V> ImmutableBiMap<K, V> of(K k1, V v1) {
38      checkEntryNotNull(k1, v1);
39      return new SingletonImmutableBiMap<K, V>(k1, v1);
40    }
41  
42    public static <K, V> ImmutableBiMap<K, V> of(K k1, V v1, K k2, V v2) {
43      return new RegularImmutableBiMap<K, V>(ImmutableMap.of(k1, v1, k2, v2));
44    }
45  
46    public static <K, V> ImmutableBiMap<K, V> of(
47        K k1, V v1, K k2, V v2, K k3, V v3) {
48      return new RegularImmutableBiMap<K, V>(ImmutableMap.of(
49          k1, v1, k2, v2, k3, v3));
50    }
51  
52    public static <K, V> ImmutableBiMap<K, V> of(
53        K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
54      return new RegularImmutableBiMap<K, V>(ImmutableMap.of(
55          k1, v1, k2, v2, k3, v3, k4, v4));
56    }
57  
58    public static <K, V> ImmutableBiMap<K, V> of(
59        K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
60      return new RegularImmutableBiMap<K, V>(ImmutableMap.of(
61          k1, v1, k2, v2, k3, v3, k4, v4, k5, v5));
62    }
63  
64    public static <K, V> Builder<K, V> builder() {
65      return new Builder<K, V>();
66    }
67  
68    public static final class Builder<K, V> extends ImmutableMap.Builder<K, V> {
69  
70      public Builder() {}
71  
72      @Override public Builder<K, V> put(K key, V value) {
73        super.put(key, value);
74        return this;
75      }
76  
77      @Override public Builder<K, V> putAll(Map<? extends K, ? extends V> map) {
78        super.putAll(map);
79        return this;
80      }
81  
82      @Override public ImmutableBiMap<K, V> build() {
83        ImmutableMap<K, V> map = super.build();
84        if (map.isEmpty()) {
85          return of();
86        }
87        return new RegularImmutableBiMap<K, V>(super.build());
88      }
89    }
90  
91    public static <K, V> ImmutableBiMap<K, V> copyOf(
92        Map<? extends K, ? extends V> map) {
93      if (map instanceof ImmutableBiMap) {
94        @SuppressWarnings("unchecked") // safe since map is not writable
95        ImmutableBiMap<K, V> bimap = (ImmutableBiMap<K, V>) map;
96        return bimap;
97      }
98  
99      if (map.isEmpty()) {
100       return of();
101     }
102 
103     ImmutableMap<K, V> immutableMap = ImmutableMap.copyOf(map);
104     return new RegularImmutableBiMap<K, V>(immutableMap);
105   }
106 
107   ImmutableBiMap(Map<K, V> delegate) {
108     super(delegate);
109   }
110 
111   public abstract ImmutableBiMap<V, K> inverse();
112 
113   @Override public ImmutableSet<V> values() {
114     return inverse().keySet();
115   }
116 
117   public final V forcePut(K key, V value) {
118     throw new UnsupportedOperationException();
119   }
120 }